using System;

namespace Tarkin.InfrastructureLibrary.Core.PrimitiveTypes
{
    /// <summary>
    /// The UnlimitedNatural class is the implementation of UnlimitedNatural primitive type as defined 
    /// by section 12.1.4 of the Unified Modeling Language: Infrastructure specfication (version 2.1.1,
    /// dated 07-02-06).
    /// 
    /// The UnlimitedNatural class is the only Tarkin implementation class for the Core::PrimitiveTypes
    /// package due to the fact that native C# constructs are used by Tarkin for the UML specified 
    /// primitive types of Boolean, integer, and string.
    /// </summary>
    public class UnlimitedNatural
    {

#region Class Constants

        /// <summary>
        /// The string value of "*" denotes a numeric value of infinity.
        /// </summary>
        public static string UnlimitedNaturalInfinity = "*";

#endregion


#region Private Members

        /// <summary>
        /// The value stored within the UnlimitedNatural. Valid values are positive integers or '*' 
        /// representing an unbounded value.
        /// </summary>
        private string value = "0";

#endregion

 
#region Constructors

        /// <summary>
        /// Default constructor.
        /// </summary>
        public UnlimitedNatural ()
        { }

        /// <summary>
        /// Overloaded constructor.
        /// </summary>
        /// <param name="value">The value stored within the UnlimitedNatural. Valid values are positive integers or '*' 
        /// representing an unbounded value.</param>
        public UnlimitedNatural ( string value )
        {
            Value = value;
        }

#endregion


#region public properties

        /// <summary>
        /// Abstract access to the UnlimitedNatural's value and implement validation logic for 
        /// setting the value.
        /// 
        /// In the event that validation logic fails and instance of the ArgumentException class 
        /// is thrown.
        /// </summary>
        public string Value
        {
            get
            {
                return value;
            }

            set
            {
                // Perform value validation logic.

                // The value of '*' denotes an unbounded value.
                if ( value == UnlimitedNaturalInfinity )
                {
                    this.value = value;

                    return;
                }

                // Verify the value is a positive integer.
                int valueAsInt;

                if ( !int.TryParse ( value, out valueAsInt ) )
                {
                    // Value is not a '*' and cannot be parsed as an integer.
                    throw new ArgumentException ( string.Format ( "UnlimitedNatural value is invalid. Value is {0}", value ) );
                }

                if ( valueAsInt < 0 )
                {
                    // Value is an integer, but not positive.
                    throw new ArgumentException ( string.Format ( "UnlimitedNatural value is a negative integer value. Value is {0}", value ) );
                }

                this.value = value;
            }
        }

#endregion

    }
}
